package com.example.poi.controller.download;


import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.meyoung.shianyun_jg.entity.Czjl.Czjl;
import com.meyoung.shianyun_jg.mapper.Czjl.CzjlMapper;
@Controller
@RequestMapping("request4")
public class ExportExcelController4 extends RecursiveAction {
	
	/**
	 * 采用forkjoin并行处理框架，本质是任务窃取算法，多线程导出大批量数据
	 */
	private static final long serialVersionUID = 1L;

	@Autowired
	private CzjlMapper czjlMapper;
	
	HttpServletResponse response;
	HttpServletRequest request;
	String tablename;
    List<Czjl> array;
     int start;
     int end;
    
   

	public ExportExcelController4() {
		super();
		// TODO Auto-generated constructor stub
	}

	//设置阀值
    private int THRESHOLD = 100; //For demo only

    public ExportExcelController4(List<Czjl> array) {
        this.array = array;
        this.start = 0;
        this.end = array.size() - 1;
    }

    public ExportExcelController4(List<Czjl> array, int start, int end) {
        this.array = array;
        this.start = start;
        this.end = end;
    }

	public ExportExcelController4(List<Czjl> array,HttpServletRequest request, String tablename, HttpServletResponse response) {
		this.array = array;
    	this.start = 0;
        this.end = array.size() - 1;
    	this.response = response;
    	this.request=request;
    	this.tablename=tablename;
	}

	
	

    @RequestMapping(value = "exportaction")
	@ResponseBody
	public void doGet(HttpServletRequest request, HttpServletResponse response,@RequestParam(value = "type", required = false)String type,@RequestParam(value = "tablename", required = false)String tablename) throws InterruptedException, UnsupportedEncodingException{
    	
    	   int SIZE = 10000;
    	
    	   ForkJoinPool forkJoinPool = new ForkJoinPool();
          
           List<Czjl> list = new ArrayList<Czjl>();
         //获取结果集
	List<Czjl> czlist = czjlMapper.queryTotal(request.getSession().getAttribute("userid").toString());
           
	/**
	 * czlist:要导出的结果集
	 * request 客户端请求
	 * tablename:生成文件名
	 * response:响应请求
	 * 
	 * 
	 */
	//提交任务，通过有参构造器的方式初始化变量，把要处理的数据传过去（执行submit后会执行compete()）
           forkJoinPool.submit(new ExportExcelController4(czlist,request,tablename, response));

           
           
           //清空response
           response.reset();
           
         //设置不同浏览器编码（防止乱码）文件名
     		response.setContentType("application/octet-stream;charset=utf-8");  
     		response.setContentType("application/vnd.ms-excel;charset=iso-8859-1");
     	    String userAgent=request.getHeader("User-Agent");
     		if (  (userAgent.indexOf("Trident")>0) && (userAgent.toUpperCase().indexOf("MSIE") > 0 || userAgent.indexOf("rv") > 0)){  
     			tablename = URLEncoder.encode(tablename, "UTF-8");  
     		} else {  
     			tablename = new String(tablename.getBytes("UTF-8"), "ISO8859-1");  
     		} 
     		
     		response.addHeader("Content-Disposition", "attachment;filename="+ tablename+".xls");
           forkJoinPool.shutdown();
           forkJoinPool.awaitTermination(1000, TimeUnit.SECONDS);
           
	}
	
	
	
	
	@Override
	protected void compute() {
    	String[] names = new String[]{"操作模块","操作类型","操作时间","操作IP"};
    	Object[] obj = creatwork(names);
    	Czjl czjl = null;
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        if (end - start < THRESHOLD){
        	//这里实际要执行的任务（满足最小拆分后）
				for (int i = 0; i < array.size(); i++) {
					obj[2]= ((HSSFSheet)obj[1]).createRow((int) i + 1);  
					czjl= array.get(i);        
					// 创建单元格，设置值       
					((HSSFRow)obj[2]).createCell(0).setCellValue(czjl.getOpModle() == null?"":czjl.getOpModle());        
					((HSSFRow)obj[2]).createCell(1).setCellValue(czjl.getOpType() == null?"":czjl.getOpType());        
					((HSSFRow)obj[2]).createCell(2).setCellValue(sdf.format(czjl.getCreateDate()));        
					((HSSFRow)obj[2]).createCell(3).setCellValue(czjl.getcIp() == null?"":czjl.getcIp());        
					}
		
			
        }else {
        	//二分法，继续拆分任务
            int middle = (start + end) /2;
            new ExportExcelController4(array, start, middle).fork();
            new ExportExcelController4(array, middle + 1, end).fork();
        }
        
        //获取响应流，并把excel文件写入响应流
        OutputStream outputStream;
		try {
			outputStream = response.getOutputStream();
      		((HSSFWorkbook)obj[0]).write(outputStream); 
      		
      		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
     
        
        
    }

   
    
  //提取工作表设置
  	public   Object[] creatwork(String[] names){
  		
  		// 1.创建一个workbook，对应一个Excel文件
  		HSSFWorkbook wb = new HSSFWorkbook();
  				// 2.在workbook中添加一个sheet，对应Excel中的一个sheet
  		HSSFSheet sheet = wb.createSheet("b");
  				// 3.在sheet中添加表头第0行
  				 HSSFRow row = sheet.createRow((int) 0);
  				// 生成一个样式，用来设置标题样式
  				 HSSFCellStyle style = wb.createCellStyle();
  				// 居中格式
  				style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
  				
  				// 设置这些样式
  				style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
  				style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  				style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
  				style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
  				style.setBorderRight(HSSFCellStyle.BORDER_THIN);
  				style.setBorderTop(HSSFCellStyle.BORDER_THIN);
  				style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
  				// 生成一个字体
  				HSSFFont font = wb.createFont();
  				font.setColor(HSSFColor.VIOLET.index);
  				font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  				// 把字体应用到当前的样式
  				style.setFont(font);
  				
  				
  				// 生成并设置另一个样式,用于设置内容样式
  				HSSFCellStyle style2 = wb.createCellStyle();
  				style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
  				style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  				style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
  				style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
  				style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
  				style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
  				style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);
  				style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  				// 生成另一个字体
  				HSSFFont font2 = wb.createFont();
  				font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
  				// 把字体应用到当前的样式
  				style2.setFont(font2);
  				
  				// 设置表格默认列宽度为15个字符
  				sheet.setDefaultColumnWidth(20);
  		
  				
  				
  				HSSFCell cell =null;
  				   
  				
  				
  				//创建表头
  				
  				for(int i = 0; i<names.length;i++){
  					cell = row.createCell(i);
  					cell.setCellValue(names[i]);
  					cell.setCellStyle(style);
  				}
  				
  				Object[] objarr = new Object[]{wb,sheet,row};
  				
  				
  				
  		        return objarr;
  	}
  	
  	
  	
  	
  	
  	
  	
}